Setting up Garage Integration
Out of the Box
Integration with your garage resource is entirely OPTIONAL, by default r14-evidence is set up to integrate with qb-garages or esx_garage to automatically load evidence when vehicles are removed from a garage or to unload evidence from the main server table when a vehicle is placed into one. This is NOT required, but makes our vehicle evidence handling on the server side a little more resource efficient as it can detect when it needs to load vehicle evidence and when it can drop it from the server table. If you have a custom garage script, the script will load evidence automatically when it is created while in the vehicle, and it will simply remain in the server-side table.
Config.VehInAndOut = { -- this OPTIONALLY configures your server side event that triggers when garaging or ungaraging a vehicle, the paramaters for base qb-garages are included, cd_garages is not supported
InEvent = Config.Framework.ESX and 'esx_garage:updateOwnedVehicle' or 'qb-garage:server:updateVehicle',
InState = Config.Framework.ESX and true or 1, -- the state receieved when placing a vehicle in a garage
InStateVar = 1, -- the argument that is received for the vehicle state when putting it in a garage
InStateVarSubfield = nil, -- the subfield of the in state var in the table that is supplied, you can use a period to search multiple subfields
InPlateVar = Config.Framework.ESX and 4 or 5, -- the argument that is received for the vehicle plate when putting it in a garage
InPlateVarSubfield = Config.Framework.ESX and 'vehicleProps.plate', -- use a . to access further subfields
OutEvent = Config.Framework.ESX and 'esx_garage:updateOwnedVehicle' or 'qb-garage:server:updateVehicleState',
OutState = Config.Framework.ESX and false or 0,
OutStateVar = 1,
OutStateVarSubfield = nil, -- the subfield of the out state var in the table that is supplied, you can use a period to search multiple subfields
OutPlateVar = Config.Framework.ESX and 4 or 2,
OutPlateVarSubfield = Config.Framework.ESX and 'vehicleProps.plate', -- use a . to access further subfields
}
Never make changes to ANY script without making a backup first, you never know what might happen!
Integrating A Third Party Script
If you desire to configure r14-evidence to integreate with your garage script, you can use the following guide to help you do so, but it is important to note that the script does not require it to function properly! By default, any existing evidence in the vehicle database will be loaded when a player either generates evidence in that vehicle, or when they search that vehicle for evidence. It will simply remain in the server evidence table until the script restarts, but will not cause issues with the script beyond taking up additional memory.
To better understand on how this config works, lets take a look at an older version of a popular modification of qb-garages by JDev, which uses a network event triggers of the same name, but with differently ordered arguments.
This script was recently modified as of 10/2022 and no longer requires a modification to the config to be compatible!
RegisterNetEvent('qb-garage:server:updateVehicle', function(state, fuel, engine, body, properties, plate, garage, location, damage)
if location and type(location) == 'vector3' then
if StoreDamageAccuratly then
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ?, parkingspot = ?, damage = ? WHERE plate = ?',{state, garage, fuel, engine, body, json.encode(properties), json.encode(location), json.encode(damage), plate})
else
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ?, parkingspot = ? WHERE plate = ?',{state, garage, fuel, engine, body, json.encode(properties), json.encode(location), plate})
end
else
if StoreDamageAccuratly then
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ?, damage = ? WHERE plate = ?',{state, garage, fuel, engine, body, json.encode(properties), json.encode(damage), plate})
else
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, fuel = ?, engine = ?, body = ?, mods = ? WHERE plate = ?', {state, garage, fuel, engine, body, json.encode(properties), plate})
end
end
end)
Here in 'qb-garage:server:updateVehicle'
we can see that our original config uses this event to track when a vehicle is returned
to it's garage, it will check the argument at the 1
position according to InStateVar
, and if it equals the value defined in
InState
r14-evidence will then save the vehicle's evidence to database and remove it from it's main evidence table. To do this, it
needs to find the plate of the vehicle in question, and checks the argument in position 5
as defined in InPlateVar
. When it does
this however, it pulls the vehicle properties table. In this case, we would need to change InPlateVar
to 6
in order it to properly
access the plate of this function!
RegisterNetEvent('qb-garage:server:updateVehicleState', function(state, plate, garage)
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, depotprice = ? WHERE plate = ?',{state, garage, 0, plate})
end)
To properly determine when a vehicle is pulled out of a garage, and to load it's evidence straight away, we again go to the server/main.lua to
find and access the 'qb-garage:server:updateVehicleState'
network event. Here, we check the OutStateVar
at position 1
and compare
it to the OutState
. When it matches this, we then pull the plate from argument 2
as defined in OutPlateVar
and r14-evidence
subsequently loads the vehicle evidence from the database.
Events With Arguments That Are Tables
If you are using a garage script which sends information using arguments which are a table containing the necessary information to either store/spawn the vehicle and it's properties, you can use the subfield variables in the config to accurately access them. Lets go ahead and create a custom version of the above event that uses a table to send all the information, and then create a configuration for it.
RegisterNetEvent('qb-garage:server:updateVehicleState', function(data)
MySQL.update('UPDATE player_vehicles SET state = ?, garage = ?, depotprice = ? WHERE plate = ?',{data.state, data.info.garage, 0, data.info.plate})
end)
Here we see instead of getting multiple arguments containing our information, we simply get one argument named data
which supplies the necessary
information for our event handler. Now we must modify our config table for garages to correctly access this table! First lets go ahead and attempt
to figure out the structure of the table. Above we can see that not only do we have the data
table, but two values stored in a table contained
within the data.info
subfield. We can use the json.enocode(data, {indent = true})
function to convert this table to a string to reveal more about how
it is structured.
data = {
state = 3, -- this is usually 0 in this and most scripts, but we will set it to 3 to demonstrate in the config how to match it
info = {
garage = 'pillbox',
plate = 'MAD OOC'
properties = {
color = 117,
fuel = 99,
}
}
}
We can see that we get the state of the vehicle (whether it is in a garage or not), as long as additional information about the vehicle that is being used by
the script to store in the database. Not all of this information is needed to integrate with r14-evidence, we simply need to find the plate being used
which we can see in the data.info.plate
table above. To access this subfield we will need to create the string info.plate
in OutPlateVarSubfield
to access
both the info subfield and then the plate value contained in it. Our config table will now look like this:
Config.VehInAndOut = { -- this OPTIONALLY configures your server side event that triggers when garaging or ungaraging a vehicle, the paramaters for base qb-garages are included, cd_garages is not supported
InEvent = Config.Framework.ESX and 'esx_garage:updateOwnedVehicle' or 'qb-garage:server:updateVehicle',
InState = Config.Framework.ESX and true or 1, -- the state receieved when placing a vehicle in a garage
InStateVar = 1, -- the argument that is received for the vehicle state when putting it in a garage
InStateVarSubfield = nil, -- the subfield of the in state var in the table that is supplied, you can use a period to search multiple subfields
InPlateVar = Config.Framework.ESX and 4 or 5, -- the argument that is received for the vehicle plate when putting it in a garage
InPlateVarSubfield = Config.Framework.ESX and 'vehicleProps.plate', -- use a . to access further subfields
OutEvent = 'qb-garage:server:updateVehicleState',
OutState = 3, -- we match the 3 received in state
OutStateVar = 1, --
OutStateVarSubfield = 'state',
OutPlateVar = 1,
OutPlateVarSubfield ='info.plate', -- use a . to access further subfields
}
We set the OutEvent
equal to the event being triggered which is 'qb-garage:server:updateVehicleState'
, becuase we recieve a state value of 3 in our table, we will want to
set OutState
equal to 3
so that it does not trigger when a vehicle is being put away. We are receiving the data
table as the first argument, so OutStateVar
remains 1
,
and this is also where we receive our plate so we will set OutPlateVar
equal to 1
as well. Finally, we need to access our plate at data.info.plate
so we set the OutPlateVarSubfield
equal ot 'info.plate'
.